package org.six11.olive.collabclient.server;

import java.util.Map;
import java.util.HashMap;
import java.util.Set;
import org.six11.util.Debug;
import org.six11.util.adt.MultiState;
import org.six11.util.adt.SynchronizedQueue;
import org.six11.util.io.Message;
import javax.servlet.ServletContextListener;
import javax.servlet.ServletContextEvent;

public class OliveServletContextListener implements ServletContextListener {


  public void contextInitialized(ServletContextEvent ev) {
    bug("Context initialized. Adding action handlers...");
    // intialize the Stellsketch state
    MultiState state = new MultiState();

    // initialize the applet message handlers, invoked from POST requests
    Map<String, AppletMessageHandler> appletMessageHandlers = new HashMap<String, AppletMessageHandler>();
    state.setValue("appletHandlers", appletMessageHandlers);
    addAppletHandler(state, "ping", new PingHandler(state));
    addAppletHandler(state, "pen", new PenHandler(state));

    // initialize the web action handlers, invoked from GET requests
    Map<String, WebActionHandler> webActionHandlers = new HashMap<String, WebActionHandler>();
    state.setValue("webHandlers", webActionHandlers);
    addWebHandler(state, "index", new DefaultWebActionHandler("index", "/index.jsp", state));

    // initialize the map of sessionID <--> msgQueue
    Map<String, SynchronizedQueue<Message>> queues = new HashMap<String, SynchronizedQueue<Message>>();
    state.setValue("message queues", queues);

    // initialize the map of roomName <--> setOfSessionIDs
    Map<String, Set<String>> roomMembership = new HashMap<String, Set<String>>();
    state.setValue("room membership", roomMembership);

    // initialize the map of sessionID <--> roomName. This is a
    // reverse index of roomMembership, and should be managed by
    // StateTool's addSessionToRoom and removeSessionFromRoom.
    Map<String, String> sessionToRoom = new HashMap<String, String>();
    state.setValue("session to room", sessionToRoom);

    // put the state object in memory so it is easily accessable from
    // other locations, such as servlets
    ev.getServletContext().setAttribute("state", state);

    bug("Done. Context fully initialized.");
  }

  
  @SuppressWarnings("unchecked")
  protected void addWebHandler(MultiState state, String name, WebActionHandler handler) {
    Map<String, WebActionHandler> webActionHandlers = (Map<String, WebActionHandler>) 
      state.getValue("webHandlers");
    webActionHandlers.put(name, handler);
  }

  @SuppressWarnings("unchecked")
  protected void addAppletHandler(MultiState state, String name, AppletMessageHandler handler) {
    Map<String, AppletMessageHandler> appletActionHandlers = (Map<String, AppletMessageHandler>) 
      state.getValue("appletHandlers");
    appletActionHandlers.put(name, handler);
  }

  public void contextDestroyed(ServletContextEvent ev) {
    bug("Context destroyed. Bye.");
  }
  
  private static void bug(String what) {
    Debug.out("OliveServletContextListener", what);
  }

}
